package kassiopeia.plugin.crawler.downloader;

import java.io.IOException;
import java.net.URL;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

public class DownloaderImpl implements Downloader {

    private final Logger logger = Logger.getLogger(DownloaderImpl.class);

    private String mimeType;
    private byte[] content;

    public DownloaderImpl(URL url, long maxContentLength) throws IOException {
        HttpClient httpClient = new DefaultHttpClient();
        try {
            doDownload(httpClient, url, maxContentLength);
        } finally {
            if(httpClient != null) {
                httpClient.getConnectionManager().shutdown();
            }
        }
    }

    @Override
    public byte[] getContent() {
        return content;
    }

    @Override
    public String getMimeType() {
        return mimeType;
    }

    private void doDownload(HttpClient httpClient, URL url, long maxContentLength) throws IOException {
        HttpGet httpget = new HttpGet(url.toExternalForm());
        HttpResponse response = httpClient.execute(httpget);

        if(!isStatusOk(response)) {
            return ;
        }

        HttpEntity entity = response.getEntity();

        if (entity == null) {
            throw new IOException("Response doesn't enclose an entity!");
        }

        if(!isContentLengthOk(entity, maxContentLength)) {
            return ;
        }

        try {
            content = EntityUtils.toByteArray(entity);
            mimeType = EntityUtils.getContentMimeType(entity);
        } catch (IOException exception) {
            httpget.abort();
            throw exception;
        }
    }

    private boolean isStatusOk(HttpResponse response) throws IOException {
        int statusCode = response.getStatusLine().getStatusCode();

        logger.debug("Status code: " + statusCode);

        if(statusCode == 200) {
            return true;
        }

        return false;
    }

    private boolean isContentLengthOk(HttpEntity entity, long maxContentLength) {
        long contentLength = entity.getContentLength()*1024;

        if(contentLength > maxContentLength) {
            logger.debug("Maximum content length exceeded: " + contentLength);
            return false;
        }

        return true;
    }
}
